﻿using System;
using UnityEngine;
using UnityEngine.Rendering;

namespace QFramework.Gun
{
    #region REQUIRE COMPONENTS
    [RequireComponent(typeof(SortingGroup))]
    [RequireComponent(typeof(SpriteRenderer))]
    [RequireComponent(typeof(Animator))]
    [RequireComponent(typeof(BoxCollider2D))]
    [RequireComponent(typeof(PolygonCollider2D))]
    [RequireComponent(typeof(Rigidbody2D))]
    [RequireComponent(typeof(Health))]
    [DisallowMultipleComponent]
    #endregion REQUIRE COMPONENTS

    public class Player : MonoBehaviour
    {
        [HideInInspector] public PlayerDetailsSO playerDetails;
        [HideInInspector] public Health health;
        [HideInInspector] public SpriteRenderer spriteRenderer;
        [HideInInspector] public Animator animator;
        [HideInInspector] public Rigidbody2D rigidbody2D;

        [SerializeField]private Transform weaponRotationPointTransform;
        [SerializeField] private Transform weaponShootPoint;
        private void Awake()
        {
            // Load components
            health = GetComponent<Health>();
            spriteRenderer = GetComponent<SpriteRenderer>();
            animator = GetComponent<Animator>();
            rigidbody2D = GetComponent<Rigidbody2D>();
            //weaponRotationPointTransform = transform.Find(Settings.WeaponShootPosition);
        }
        
        private void Start()
        {
            //订阅事件
            EventCenter.Instance.AddEventListener(EventEnumType.player_idle, OnPlayerIdle);
            EventCenter.Instance.AddEventListener<AimWeapon>(EventEnumType.aim_weapon, OnAimWeapon);
            EventCenter.Instance.AddEventListener<PlayerMove>(EventEnumType.player_move, OnPlayerMove);
            EventCenter.Instance.AddEventListener<PlayerRoll>(EventEnumType.player_roll, OnPlayerRoll);
        }



        #region 事件相关
        private void OnPlayerRoll(PlayerRoll arg)
        {
            InitializeAimAnimationParameters();
            InitializeRollAnimationParameters();
            SetMovementToPositionAnimationParameters(arg);
            rigidbody2D.velocity = arg.rollDirection * playerDetails.rollSpeed;
        }
        
        private void SetMovementToPositionAnimationParameters(PlayerRoll arg)
        {
            if (arg.rollDirection.x > 0f)
            {
                animator.SetBool(Settings.rollRight, true);
            }
            else if (arg.rollDirection.x < 0f)
            {
                animator.SetBool(Settings.rollLeft, true);
            }
            else if (arg.rollDirection.y > 0f)
            {
                animator.SetBool(Settings.rollUp, true);
            }
            else if (arg.rollDirection.y < 0f)
            {
                animator.SetBool(Settings.rollDown, true);
            }
        }
        private void InitializeRollAnimationParameters()
        {
            animator.SetBool(Settings.rollDown, false);
            animator.SetBool(Settings.rollRight, false);
            animator.SetBool(Settings.rollLeft, false);
            animator.SetBool(Settings.rollUp, false);
        }

        private void OnPlayerMove(PlayerMove arg)
        {
            animator.SetBool(Settings.isMoving, true);
            animator.SetBool(Settings.isIdle, false);
            rigidbody2D.velocity = arg.moveDirection*playerDetails.moveSpeed;
        }
        private void OnAimWeapon(AimWeapon arg)
        {
            InitializeAimAnimationParameters();
            InitializeRollAnimationParameters();
            SetAimWeaponAnimationParameters(arg.aimDirection);
            AimWeapon(arg.aimDirection, arg.weaponAimAngle);
        }

        private void InitializeAimAnimationParameters()
        {
            animator.SetBool(Settings.aimUp, false);
            animator.SetBool(Settings.aimUpRight, false);
            animator.SetBool(Settings.aimUpLeft, false);
            animator.SetBool(Settings.aimRight, false);
            animator.SetBool(Settings.aimLeft, false);
            animator.SetBool(Settings.aimDown, false);
        }
        private void SetAimWeaponAnimationParameters(AimDirection aimDirection)
        {
            // Set aim direction
            switch (aimDirection)
            {
                case AimDirection.Up:
                    animator.SetBool(Settings.aimUp, true);
                    break;

                case AimDirection.UpRight:
                    animator.SetBool(Settings.aimUpRight, true);
                    break;

                case AimDirection.UpLeft:
                    animator.SetBool(Settings.aimUpLeft, true);
                    break;

                case AimDirection.Right:
                    animator.SetBool(Settings.aimRight, true);
                    break;

                case AimDirection.Left:
                    animator.SetBool(Settings.aimLeft, true);
                    break;

                case AimDirection.Down:
                    animator.SetBool(Settings.aimDown, true);
                    break;

            }

        }
        
        private void AimWeapon(AimDirection aimDirection, float aimAngle)
        {
            // Set angle of the weapon transform
            weaponRotationPointTransform.eulerAngles = new Vector3(0f, 0f, aimAngle);

            // Flip weapon transform based on player direction
            switch (aimDirection)
            {
                case AimDirection.Left:
                case AimDirection.UpLeft:
                    weaponRotationPointTransform.localScale = new Vector3(1f, -1f, 0f);
                    break;

                case AimDirection.Up:
                case AimDirection.UpRight:
                case AimDirection.Right:
                case AimDirection.Down:
                    weaponRotationPointTransform.localScale = new Vector3(1f, 1f, 0f);
                    break;
            }

        }

        private void OnPlayerIdle()
        {
            animator.SetBool(Settings.isMoving, false);
            animator.SetBool(Settings.isIdle, true);
            
            rigidbody2D.velocity = Vector2.zero;
        }

        #endregion
        
        public Vector3 GetWeaponRotationPointPosition()
        {
            return weaponRotationPointTransform.position;
        }

        public Vector3 GetWeaponShootPosition()
        {
            return weaponShootPoint.position;
        }
        
        
        
        private void OnDestroy()
        {
            //移除订阅事件
            EventCenter.Instance.RemoveEventListener(EventEnumType.player_idle, OnPlayerIdle);
            EventCenter.Instance.RemoveEventListener<AimWeapon>(EventEnumType.aim_weapon, OnAimWeapon);
            EventCenter.Instance.RemoveEventListener<PlayerMove>(EventEnumType.player_move, OnPlayerMove);
            EventCenter.Instance.RemoveEventListener<PlayerRoll>(EventEnumType.player_roll, OnPlayerRoll);
        }
        
        public void Initialize(PlayerDetailsSO playerDetails)
        {
            this.playerDetails = playerDetails;

            // Set player starting health
            SetPlayerHealth();
        }
        
        private void SetPlayerHealth()
        {
            health.SetStartingHealth(playerDetails.playerHealthAmount);
        }
    }
}